using System;
using Coderoom.ScrumPlanner.Data;
using Coderoom.ScrumPlanner.Domain;
using Coderoom.ScrumPlanner.Tests.FakeRepositories;
using Xunit;

namespace Coderoom.ScrumPlanner.Tests.Unit.ServiceTests
{
	public class UserStoryServiceTests
	{
		private readonly UserStoryService _service;

		public UserStoryServiceTests()
		{
			var repository = new FakeUserStoryRepository();
			_service = new UserStoryService(repository);
		}

		[Fact]
		public void GetUserStoriesByThemeId_returns_UserStoryCollection()
		{
			// arrange
			var themeId = new Guid("AEA523B9-DE70-4660-BD78-2741BFCCFCCA");

			// act
			var userStories = _service.GetUserStories(themeId);

			// assert
			Assert.NotNull(userStories);
			Assert.IsType<UserStoryCollection>(userStories);
			Assert.Equal(2, userStories.Count);

			Assert.Equal(new Guid("5DB514B6-BFDC-44BC-AD75-7AF8D3BF0D71"), userStories[0].Id);
			Assert.Equal("UserStory A", userStories[0].Title);
			Assert.Equal("userstory-a", userStories[0].Slug);

			Assert.Equal(new Guid("A5960D03-0648-4D17-BF55-8C0E86DDEC32"), userStories[1].Id);
			Assert.Equal("UserStory B", userStories[1].Title);
			Assert.Equal("userstory-b", userStories[1].Slug);
		}

		[Fact]
		public void GetUserStory_returns_UserStory_when_userstory_is_found()
		{
			// arrange
			var id = new Guid("A5960D03-0648-4D17-BF55-8C0E86DDEC32");

			// act
			var userStory = _service.GetUserStory(id);

			// assert
			Assert.NotNull(userStory);
			Assert.IsType<UserStory>(userStory);
			Assert.Equal(new Guid("A5960D03-0648-4D17-BF55-8C0E86DDEC32"), userStory.Id);
			Assert.Equal("UserStory B", userStory.Title);
			Assert.Equal("userstory-b", userStory.Slug);
		}

		[Fact]
		public void GetUserStory_returns_null_when_userstory_is_not_found()
		{
			// arrange
			var id = Guid.Empty;

			// act
			var userStory = _service.GetUserStory(id);

			// assert
			Assert.Null(userStory);
		}

		[Fact]
		public void CreateUserStory_returns_void_when_userstory_is_created()
		{
			// arrange
			var themeId = new Guid("AEA523B9-DE70-4660-BD78-2741BFCCFCCA");
			var userStories = _service.GetUserStories(themeId);
			Assert.Equal(2, userStories.Count);

			var newUserStory = new UserStory();
			newUserStory.Title = "UserStory C";
			newUserStory.Slug = "userstory-c";
			newUserStory.ThemeId = themeId;

			// act
			_service.CreateUserStory(newUserStory);

			// assert
			userStories = _service.GetUserStories(themeId);

			Assert.Equal(3, userStories.Count);

			Assert.NotEqual(Guid.Empty, userStories[2].Id);
			Assert.Equal("UserStory C", userStories[2].Title);
			Assert.Equal("userstory-c", userStories[2].Slug);
			Assert.Equal(themeId, userStories[2].ThemeId);
		}

		[Fact]
		public void CreateUserStory_throws_ArgumentNullException_when_userstory_with_null_title_is_passed()
		{
			// arrange
			var userStory = new UserStory();

			// act
			Assert.Throws<ArgumentException>(() => _service.CreateUserStory(userStory));
		}

		[Fact]
		public void CreateUserStory_throws_ArgumentException_when_userstory_with_empty_title_is_passed()
		{
			// arrange
			var userStory = new UserStory();
			userStory.Title = string.Empty;

			// act
			Assert.Throws<ArgumentException>(() => _service.CreateUserStory(userStory));
		}

		[Fact]
		public void DeleteUserStory_returns_true_when_userstory_is_deleted()
		{
			// arrange
			var themeId = new Guid("AEA523B9-DE70-4660-BD78-2741BFCCFCCA");

			Assert.Equal(2, _service.GetUserStories(themeId).Count);

			var id = _service.GetUserStories(themeId)[1].Id;

			// act
			var result = _service.DeleteUserStory(id);

			// assert
			Assert.True(result);
			Assert.Equal(1, _service.GetUserStories(themeId).Count);
		}

		[Fact]
		public void DeleteUserStory_returns_false_when_userstory_is_not_deleted()
		{
			// arrange
			var themeId = new Guid("AEA523B9-DE70-4660-BD78-2741BFCCFCCA");

			Assert.Equal(2, _service.GetUserStories(themeId).Count);

			var id = Guid.Empty;

			// act
			var result = _service.DeleteUserStory(id);

			// assert
			Assert.False(result);
			Assert.Equal(2, _service.GetUserStories(themeId).Count);
		}
	}
}